之前我們在前面的篇章知道了如何使用 大括號 {} 來幫助我們顯示變數資料。而有時候我們會想顯示不只一項資料,而是從擁有數個 值 得 陣列(Array) 中,顯示我們想要的資料。今天就要來介紹如何在 React Component 裡面來顯示一個列表資料。參考的官方文件:
用一個棒球隊伍球員當作例子,如果我們想要顯示該球隊的球員資料,我們可以寫成這樣:
function PlayerList() {
return (
<ul>
<li>林澤彬</li>
<li>林岳谷</li>
<li>張育成</li>
<li>范國宸</li>
</ul>
)
}
把隊員一個一個寫出來,但我們知道,一隊會有數十名球員,如果要一個一個增加會很麻煩,而且當資料有所變動的時候,要從數十行的程式碼裡面找到想要修改的地方也會變得十分困難。這時候就可以把資料存在一個陣列中,並且使用 map() 方法讓 React 把所有資料 render 出來。實際寫出來會變成:
const players = ['林澤彬', '林岳谷', '張育成', '范國宸']
function PlayerList() {
return (
<ul>
{plyers.map(player => <li>{player}</li>)}
</ul>
)
}
如此一來,之後再增加 players 裡的資料,也不用再多加程式碼了,可以讓我們的 Component 更精簡。
順便簡單介紹 map,簡單來說他會把原本陣列裡的資料走過一遍,然後再透過元陣列裡的內容重組一個新的陣列,這邊就是把原本的 字串(String) 變成 JSX 的節點陣列。這也是 JavaScript 原生的功能,所以也可以寫在 JSX 外面也是沒問題的。在之後也是會非常常使用的方法。
在執行上述程式碼的時候,如果打開 Console,會發現有顯示一條錯誤訊息的 Warning:
Warning: Each child in a list should have a unique “key” prop.
跟我們說在陣列的每個 child 必須要有一個具唯一性的 key prop,接下來會介紹為什麼會有這個錯誤。
我們在使用 map 來 render 列表的時候,每個 child 都會需要一個獨特的 key 值來辨識。這個 key 是讓 React 能知道陣列每個 item 所對應的位置,讓之後陣列更新的時候,相對應的資料能在對的位置。在一些資料的操作都會有影響,像是 排列(Sorting)、資料的新增與更新還有刪除。在資料改變後,React 還能透過 key 找到應該更新的 item,這也是為什麼 key 需要是具有唯一性的值,不然當有重複的 key 的時候 React 會不知道哪個正式對的。
因為要給 key 我們就需要把剛剛的資料稍微改一下:
const players = [{
id: 1,
name: '林澤彬'
}, {
id: 2,
name: '林岳谷'
}, {
id: 3,
name: '張育成'
}, {
id: 4,
name: '范國宸'
}]
function PlayerList() {
return (
<ul>
{plyers.map(player => <li key={player.id}>{player.name}</li>)}
</ul>
)
}
通常 key 的來源會有:
key 或 id,來確保唯一性,並且更能代表資料內容。id 存在本機端確保資料的唯一性。關於 key 還有一些規則,那就是他的唯一是只有在 Slibings 之間,也就是說在 render 的一個陣列裡的資料需要 key 唯一,但如果是在其他地方使用不同陣列,是可以使用相同的 key 的。不過通常我自己在寫還是會讓他們不一樣,這樣除了以防萬一,在查找程式碼的時候也會有幫助。
另外就是不要動態產生 key,讓每次同個資料都有不同的 key,這樣會讓 React 把該資料每次都認為是不同的東西,這讓 render 的效率變低,因為變成每次都要重新建立一個新的節點。
有些人開發會塞陣列的 索引值 index 當作 key,這是當沒傳入 key 值的時候預設,但這也跟動態產生 key 一樣,會變成同個資料可能會在經過資料更改後有不同的 key,造成效率與顯示錯誤訊息的問題。所以也是不推薦直接使用 index。
今天介紹了如何在 React 上 render 一個列表,現在也算是簡單的開頭,之後還會有一些考慮龐大的資料量時的效率問題等。之後的篇章也會有更多進階的延伸。key 的應該用則也是 React 一大重點。另外只要是陣列(Array)上的應該用,都一樣可以在 React Component 裡使用像是,filter(), sort() 等方法,也可搭配 map 使用。大家也可以多加嘗試。
今天的文章大概到這邊,感謝大家耐心地看完今天的文章,有任何問題與建議歡迎告訴我,明天見,晚安。